//
//  Pinyin.swift
//  LogisticsCargoOwner
//
//  Created by safiri on 2020/8/4.
//  Copyright © 2020 qiluys. All rights reserved.
//

import Foundation


   //****************************************************************************************************
   //*  某些字作为姓氏时，读音比较特别，系统默认转换时有时不能转成正确的读音，以下列出的姓氏常见的多音字姓氏
   //*  【如果有其他未列出且系统默认翻译不能匹配正确读音的多音字姓氏时，请补全。以下多音字在iOS7、iOS8、iOS9设备上均已测试】
   //*
   //*  繁：pó 姓氏时不读fán。汉末诗人繁钦。系统默认将该字翻译成fán
   //*  区：ōu 姓氏时不读qū。前国足门将区楚良。系统翻译默认将该字翻译成qū
   //*  仇：qiú 姓氏时不读chóu。明代画家仇英。系统翻译默认将该字翻译成chóu
   //*  种：chóng 姓氏时不读zhǒng。原中国驻阿拉伯也门大使种汉九。系统翻译默认将该字翻译成zhǒng
   //*  单：shàn 姓氏时不读dān。隋唐单雄信。系统翻译默认将该字翻译成dān
   //*  解：xiè 姓氏时不读jiě。梁山好汉解珍、解宝。系统翻译默认将该字翻译成jiě
   //*  查：zhā 姓氏时不读chá。著名武侠小说作家金庸本名查良镛。系统翻译默认将该字翻译成chá
   //*  曾：zēng 姓氏时不读céng。宋代作家曾巩、清代名臣曾国藩，香港特首曾荫权。系统翻译默认将该字翻译成céng
   //*  秘：bì 姓氏时不读mì。系统默认将该字翻译成mì
   //*  乐：yuè 姓氏时不读lè。系统默认将该字翻译成lè
   //*  重：chóng 姓氏时不读zhòng。系统默认将该字翻译成zhòng
   //*  朴：piáo 韩国三大姓，李、金、朴，姓氏时不读pǔ。系统翻译默认将该字翻译成pǔ
   //*  缪: miào 姓氏时不读móu。系统翻译默认将该字翻译成móu
   //【系统翻译就是姓氏发音】冼: xiǎn 姓氏时不读shěng。系统翻译默认将该字翻译成xiǎn
   //*  翟：zhái 姓氏时不读dí。系统翻译默认将该字翻译成dí
   //*  折：shé  姓氏时不读zhē折腾或者zhé折叠。系统翻译默认将该字翻译成zhé
   //*  黑：hè  姓氏时不读hēi。系统翻译默认将该字翻译成hēi
   //*  盖：gě 姓氏时不读gài。系统翻译默认将该字翻译成gài
   //*  沈：shěn 姓氏时不读chén。系统翻译默认将该字翻译成chén
   //*  尉迟：yù chí 复姓。系统翻译默认将该字翻译成wèi chí
   //*  万俟：mò qí  复姓。系统翻译默认将该字翻译成wàn qí
   //*【谌，读音作chén。因南北方文化差异不同，用作姓氏时即读chén也可读shèn。考虑效率问题所以未录入，以系统翻译为准】
   //****************************************************************************************************
   
   // MARK: - 明确列出转换平台翻译错误的多音字姓氏，并列出正确匹配项
   /**
       *  所有的多音字匹配的拼音键值对，每个姓氏多音字对应一个数组，数组中第一个字为正确发音，第二个为错误发音，错误发音用来做字符串替换使用
       *  多音字姓氏使用系统默认转换时，如果转换错误，将使用该键值对匹配替换
   */
    let dicForAllPolyphoneSurnamePinYin: [String: Array<String>] = ["繁":["po","fan"],
                                                                      "区":["ou","qu"],
                                                                      "仇":["qiu","chou"],
                                                                      "种":["chong","zhong"],
                                                                      "单":["shan","dan"],
                                                                      "解":["xie","jie"],
                                                                      "查":["zha","cha"],
                                                                      "曾":["zeng","ceng"],
                                                                      "秘":["bi","mi"],
                                                                      "乐":["yue","le"],
                                                                      "重":["chong","zhong"],
                                                                      "朴":["piao","pu"],
                                                                      "缪":["miao","mou"],
                                                                      "翟":["zhai","di"],
                                                                      "折":["she","zhe"],
                                                                      "黑":["he","hei"],
                                                                      "盖":["ge","gai"],
                                                                      "沈":["shen","chen"],
                                                                      "尉迟":["yu chi","wei chi"],
                                                                      "万俟":["mo qi","wan qi"],
                                                                      "长":["chang","zhang"]]
   
   /**
       *  所有多音字匹配的带音调拼音键值对，每个姓氏多音字对应一个数组，数组中第一个字为正确发音，第二个为错误发音，错误发音用来做字符串替换使用
       *  多音字姓氏使用系统默认转换时，如果转换错误，将使用该键值对匹配替换
   */
    let dicForAllPolyphoneSurnamePinYinWithYinDiao: [String: Array<String>] = ["繁":["pó","fán"],
                                                                           "区":["ōu","qū"],
                                                                           "仇":["qiú","chóu"],
                                                                           "种":["chóng","zhǒng"],
                                                                           "单":["shàn","dān"],
                                                                           "解":["xiè","jiě"],
                                                                           "查":["zhā","chá"],
                                                                           "曾":["zēng","céng"],
                                                                           "秘":["bì","mì"],
                                                                           "乐":["yuè","lè"],
                                                                           "重":["chóng","zhòng"],
                                                                           "朴":["piáo","pǔ"],
                                                                           "缪":["miào","móu"],
                                                                           "冼":["xiǎn","shěng"],
                                                                           "翟":["zhái","dí"],
                                                                           "折":["shé","zhé"],
                                                                           "黑":["hè","hēi"],
                                                                           "盖":["gě","gài"],
                                                                           "沈":["shěn","chén"],
                                                                           "尉迟":["yù chí","wèi chí"],
                                                                           "万俟":["mò qí","wàn qí"],
                                                                           "长" :["cháng","zhǎng"]]

    /**
        *  所有的多音字匹配的拼音首字母键值对，每个姓氏多音字对应一字符串
        *  多音字姓氏使用第三方平台转换时，如果转换错误，将使用该键值对匹配替换
    */
    let dicForAllPolyphoneSurnameFirstLetters: [String: String] = ["繁":"p",
                                                                      "区":"o",
                                                                      "仇":"q",
                                                                      "种":"c",
                                                                      "单":"s",
                                                                      "解":"x",
                                                                      "查":"z",
                                                                      "曾":"z",
                                                                      "秘":"b",
                                                                      "乐":"y",
                                                                      "重":"c",
                                                                      "冼":"x",
                                                                      "翟":"z",
                                                                      "折":"s",
                                                                      "沈":"s",
                                                                      "尉迟":"yc",
                                                                      "万俟":"mq",
                                                                      "长":"c"]

public extension String {
    /**
     *  把字符串中的汉字转换成拼音
     
     *  @param isForSurname 明确字符串是否表示姓名
     *  @param bFlag        明确字符串转换完毕后是否需要拼音音调
     
     *  @return 返回结果不做特殊处理，请注意系统默认转换汉字时采用小写拼音
     */
    func pinyinForSort(isForSurname: Bool = false, withYindiao yindiao: Bool = false) -> String {
        var convertString = self
        if isForSurname { //如果是姓名优先去掉“·”符号
            convertString = convertString.replacingOccurrences(of: "·", with: "")
        }
        let mutableString = NSMutableString(string: convertString)
        _ = CFStringTransform(mutableString as CFMutableString, nil, kCFStringTransformToLatin, false)
        if yindiao {
            var pinyinString = mutableString as String
            if isForSurname {
                //处理姓氏多音字
                let allPolyphoneSurname = dicForAllPolyphoneSurnamePinYinWithYinDiao.keys
                for tempPolyphoneSurname in allPolyphoneSurname {
                    if convertString .hasPrefix(tempPolyphoneSurname) {
                        // 如果要转换的字符串有多音字的姓氏
                        let arrayOfPolyphoneSurnamePinYinWithYinDiao = dicForAllPolyphoneSurnamePinYinWithYinDiao[tempPolyphoneSurname]!
                        let rightPinYin = arrayOfPolyphoneSurnamePinYinWithYinDiao[0]
                        let wrongPinYin = arrayOfPolyphoneSurnamePinYinWithYinDiao[1]
                        if pinyinString.contains(wrongPinYin) {
                            let range = pinyinString.startIndex..<pinyinString.index(pinyinString.startIndex, offsetBy: wrongPinYin.count)
                            pinyinString.replaceSubrange(range, with: rightPinYin)
                        }
                        break
                    }
                }
            }
            return pinyinString
        }
        else {
            // 不用音调
            var pinyinString = mutableString.folding(options: String.CompareOptions.diacriticInsensitive, locale: Locale.current)
            
            if isForSurname {
                //处理姓氏多音字
                let allPolyphoneSurname = dicForAllPolyphoneSurnamePinYin.keys
                for tempPolyphoneSurname in allPolyphoneSurname {
                    if convertString .hasPrefix(tempPolyphoneSurname) {
                        // 如果要转换的字符串有多音字的姓氏
                        let arrayOfPolyphoneSurnamePinYin = dicForAllPolyphoneSurnamePinYin[tempPolyphoneSurname]!
                        let rightPinYin = arrayOfPolyphoneSurnamePinYin[0]
                        let wrongPinYin = arrayOfPolyphoneSurnamePinYin[1]
                        if pinyinString.contains(wrongPinYin) { //"di - di tian long"
                            let range = pinyinString.startIndex..<pinyinString.index(pinyinString.startIndex, offsetBy: wrongPinYin.count)
                            pinyinString.replaceSubrange(range, with: rightPinYin)
                        }
                        break
                    }
                }
            }
            return pinyinString
        }
    }
    
    /// 字符串首字母转换功能，非英文或汉字返回原字符串
    /// - Parameter isForSurname: 是否区分多音字姓名
    /// - Returns: 首字母字符串
    func firstLetters(isForSurname: Bool = false) -> String {
        
        var convertString = self
        var resultString = ""
        if isForSurname { //如果是姓名优先去掉“·”符号
            convertString = convertString.replacingOccurrences(of: "·", with: "")
        }
        
        if convertString.count > 0 {
            
            for indexChar in convertString {
                //判断字符是否为英文字母
                if (indexChar >= "A" && indexChar <= "Z") || (indexChar >= "a" && indexChar <= "z") {
                    resultString.append(indexChar)
                }
                else if "\u{4E00}" <= indexChar && indexChar <= "\u{9FA5}" {
                    //判断字符是否为汉字
                    resultString.append("\(indexChar)".findFirstLetter())
                }else {
                    resultString.append(indexChar)
                }
            }
            if isForSurname {
                //处理姓氏多音字
                let allPolyphoneSurname = dicForAllPolyphoneSurnameFirstLetters.keys
                for tempPolyphoneSurname in allPolyphoneSurname {
                    if convertString.hasPrefix(tempPolyphoneSurname),
                        let right = dicForAllPolyphoneSurnameFirstLetters[tempPolyphoneSurname] {
                        let range = resultString.startIndex..<resultString.index(resultString.startIndex, offsetBy: tempPolyphoneSurname.count)
                        resultString.replaceSubrange(range, with: right)
                        break
                    }
                }
            }
        }
        return resultString
    }
    
    //获取拼音首字母（大写字母）
    func findFirstLetter() -> String {
        //转变成可变字符串
        let mutableString = NSMutableString.init(string: self)

        //将中文转换成带声调的拼音
        CFStringTransform(mutableString as CFMutableString, nil,      kCFStringTransformToLatin, false)

        //去掉声调
        let pinyinString = mutableString.folding(options:          String.CompareOptions.diacriticInsensitive, locale: NSLocale.current)

        //将拼音首字母换成大写
        let strPinYin = pinyinString.uppercased()

        //截取大写首字母
//        let firstString = strPinYin.substring(to:strPinYin.index(strPinYin.startIndex, offsetBy: 1))
        let firstString = String(strPinYin[strPinYin.startIndex..<strPinYin.index(strPinYin.startIndex, offsetBy: 1)])
        

        //判断首字母是否为大写
        let regexA = "^[A-Z]$"
        let predA = NSPredicate.init(format: "SELF MATCHES %@", regexA)
        return predA.evaluate(with: firstString) ? firstString : "#"
    }
    
}

/** example
 

let a = "百度".pinyinForSort()
print("百度不要音调，不是姓名--\(a)")
let b = "百度".pinyinForSort(isForSurname: false, withYindiao: true)
print("百度要音调，不是姓名--\(b)")
let c = "翟天龙".pinyinForSort(isForSurname: false, withYindiao: true)
print("翟天龙要音调，不是姓名--\(c)")
let d = "翟天龙".pinyinForSort(isForSurname: true, withYindiao: true)
print("翟天龙要音调，是姓名--\(d)")
let e = "翟天龙".pinyinForSort(isForSurname: true, withYindiao: false)
print("翟天龙要音调，是姓名--\(e)")

"中国共产党万岁！".forEach { (s) in
    let str = "\(s)".firstLetters()
    print("\(s)首字母为\(str)")
    
}
for s in "仇千人" {
    let str = "\(s)".firstLetters()
    print("\(s)首字母为\(str)")
}
for s in "仇千人" {
    let str = "\(s)".firstLetters(isForSurname: true)
    print("\(s)首字母为\(str)")
}
 
 百度不要音调，不是姓名--bai du
 百度要音调，不是姓名--bǎi dù
 翟天龙要音调，不是姓名--dí tiān lóng
 翟天龙要音调，是姓名--zhái tiān lóng
 翟天龙要音调，是姓名--zhai tian long

 中首字母为Z
 国首字母为G
 共首字母为G
 产首字母为C
 党首字母为D
 万首字母为W
 岁首字母为S
 ！首字母为#
 仇首字母为C
 千首字母为Q
 人首字母为R
 仇首字母为q
 千首字母为Q
 人首字母为R

 */
